home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / src / linux-headers-2.6.28-15 / include / asm-generic / bitops / non-atomic.h < prev    next >
Encoding:
C/C++ Source or Header  |  2008-12-24  |  3.0 KB  |  109 lines

  1. #ifndef _ASM_GENERIC_BITOPS_NON_ATOMIC_H_
  2. #define _ASM_GENERIC_BITOPS_NON_ATOMIC_H_
  3.  
  4. #include <asm/types.h>
  5.  
  6. /**
  7.  * __set_bit - Set a bit in memory
  8.  * @nr: the bit to set
  9.  * @addr: the address to start counting from
  10.  *
  11.  * Unlike set_bit(), this function is non-atomic and may be reordered.
  12.  * If it's called on the same region of memory simultaneously, the effect
  13.  * may be that only one operation succeeds.
  14.  */
  15. static inline void __set_bit(int nr, volatile unsigned long *addr)
  16. {
  17.     unsigned long mask = BIT_MASK(nr);
  18.     unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
  19.  
  20.     *p  |= mask;
  21. }
  22.  
  23. static inline void __clear_bit(int nr, volatile unsigned long *addr)
  24. {
  25.     unsigned long mask = BIT_MASK(nr);
  26.     unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
  27.  
  28.     *p &= ~mask;
  29. }
  30.  
  31. /**
  32.  * __change_bit - Toggle a bit in memory
  33.  * @nr: the bit to change
  34.  * @addr: the address to start counting from
  35.  *
  36.  * Unlike change_bit(), this function is non-atomic and may be reordered.
  37.  * If it's called on the same region of memory simultaneously, the effect
  38.  * may be that only one operation succeeds.
  39.  */
  40. static inline void __change_bit(int nr, volatile unsigned long *addr)
  41. {
  42.     unsigned long mask = BIT_MASK(nr);
  43.     unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
  44.  
  45.     *p ^= mask;
  46. }
  47.  
  48. /**
  49.  * __test_and_set_bit - Set a bit and return its old value
  50.  * @nr: Bit to set
  51.  * @addr: Address to count from
  52.  *
  53.  * This operation is non-atomic and can be reordered.
  54.  * If two examples of this operation race, one can appear to succeed
  55.  * but actually fail.  You must protect multiple accesses with a lock.
  56.  */
  57. static inline int __test_and_set_bit(int nr, volatile unsigned long *addr)
  58. {
  59.     unsigned long mask = BIT_MASK(nr);
  60.     unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
  61.     unsigned long old = *p;
  62.  
  63.     *p = old | mask;
  64.     return (old & mask) != 0;
  65. }
  66.  
  67. /**
  68.  * __test_and_clear_bit - Clear a bit and return its old value
  69.  * @nr: Bit to clear
  70.  * @addr: Address to count from
  71.  *
  72.  * This operation is non-atomic and can be reordered.
  73.  * If two examples of this operation race, one can appear to succeed
  74.  * but actually fail.  You must protect multiple accesses with a lock.
  75.  */
  76. static inline int __test_and_clear_bit(int nr, volatile unsigned long *addr)
  77. {
  78.     unsigned long mask = BIT_MASK(nr);
  79.     unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
  80.     unsigned long old = *p;
  81.  
  82.     *p = old & ~mask;
  83.     return (old & mask) != 0;
  84. }
  85.  
  86. /* WARNING: non atomic and it can be reordered! */
  87. static inline int __test_and_change_bit(int nr,
  88.                         volatile unsigned long *addr)
  89. {
  90.     unsigned long mask = BIT_MASK(nr);
  91.     unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
  92.     unsigned long old = *p;
  93.  
  94.     *p = old ^ mask;
  95.     return (old & mask) != 0;
  96. }
  97.  
  98. /**
  99.  * test_bit - Determine whether a bit is set
  100.  * @nr: bit number to test
  101.  * @addr: Address to start counting from
  102.  */
  103. static inline int test_bit(int nr, const volatile unsigned long *addr)
  104. {
  105.     return 1UL & (addr[BIT_WORD(nr)] >> (nr & (BITS_PER_LONG-1)));
  106. }
  107.  
  108. #endif /* _ASM_GENERIC_BITOPS_NON_ATOMIC_H_ */
  109.